﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Globalization;
#endregion

namespace NetBay.Core.Tools
{
    /// <summary>
    /// 
    /// </summary>
    public class ConvertNumberToLetter
    {
        /// <summary>
        /// Converts the number to text.
        /// </summary>
        /// <param name="p_dNumber">The number.</param>
        /// <returns></returns>
        public static string ConvertNumberToText(
            decimal p_dNumber,
            string p_sCurrencyText)
        {
            switch (CultureInfo.CurrentCulture.TwoLetterISOLanguageName)
            {
                case "fr":
                    return ConvertNumberToTextFr(p_dNumber, p_sCurrencyText);
                case "en":
                    return ConvertNumberToTextEn(p_dNumber, p_sCurrencyText);
                default:
                    return ConvertNumberToTextEn(p_dNumber, p_sCurrencyText);
            }
        }

        #region French Number
        /// <summary>
        /// Converts the number to text fr.
        /// </summary>
        /// <param name="p_dNumber">The number.</param>
        /// <returns></returns>
        public static string ConvertNumberToTextFr(decimal p_dNumber, string p_sCurrencyText)
        {
            decimal integerPart = Math.Truncate(p_dNumber);
            decimal decimalPart = (p_dNumber - integerPart) * 100;

            string integerPartString = "";

            integerPartString = string.Format("{0} {1}",
                ConvertNumberFr(integerPart),
                p_sCurrencyText);

            string decimalPartString = string.Empty;
            if (decimalPart > 0)
            {
                decimalPartString = String.Format(" {0}", ConvertNumberFr(decimalPart));
            }

            return String.Format(
                "{0}{1}",
                integerPartString,
                decimalPartString).Trim();

        }

        /// <summary>
        /// Converts the number fr.
        /// </summary>
        /// <param name="p_dChiffre">The chiffre.</param>
        /// <returns></returns>
        private static string ConvertNumberFr(decimal p_dChiffre)
        {
            int centaine, dizaine, unite, reste, y;
            bool dix = false;
            string lettre = "";
            //strcpy(lettre, "");

            reste = (int)p_dChiffre;

            for (int i = 1000000000; i >= 1; i /= 1000)
            {
                y = reste / i;
                if (y != 0)
                {
                    centaine = y / 100;
                    dizaine = (y - centaine * 100) / 10;
                    unite = y - (centaine * 100) - (dizaine * 10);
                    switch (centaine)
                    {
                        case 0:
                            break;
                        case 1:
                            lettre += "cent ";
                            break;
                        case 2:
                            if ((dizaine == 0) && (unite == 0)) lettre += "deux cents ";
                            else lettre += "deux cent ";
                            break;
                        case 3:
                            if ((dizaine == 0) && (unite == 0)) lettre += "trois cents ";
                            else lettre += "trois cent ";
                            break;
                        case 4:
                            if ((dizaine == 0) && (unite == 0)) lettre += "quatre cents ";
                            else lettre += "quatre cent ";
                            break;
                        case 5:
                            if ((dizaine == 0) && (unite == 0)) lettre += "cinq cents ";
                            else lettre += "cinq cent ";
                            break;
                        case 6:
                            if ((dizaine == 0) && (unite == 0)) lettre += "six cents ";
                            else lettre += "six cent ";
                            break;
                        case 7:
                            if ((dizaine == 0) && (unite == 0)) lettre += "sept cents ";
                            else lettre += "sept cent ";
                            break;
                        case 8:
                            if ((dizaine == 0) && (unite == 0)) lettre += "huit cents ";
                            else lettre += "huit cent ";
                            break;
                        case 9:
                            if ((dizaine == 0) && (unite == 0)) lettre += "neuf cents ";
                            else lettre += "neuf cent ";
                            break;
                    }// endSwitch(centaine)

                    switch (dizaine)
                    {
                        case 0:
                            break;
                        case 1:
                            dix = true;
                            break;
                        case 2:
                            lettre += "vingt ";
                            break;
                        case 3:
                            lettre += "trente ";
                            break;
                        case 4:
                            lettre += "quarante ";
                            break;
                        case 5:
                            lettre += "cinquante ";
                            break;
                        case 6:
                            lettre += "soixante ";
                            break;
                        case 7:
                            dix = true;
                            lettre += "soixante ";
                            break;
                        case 8:
                            if (unite == 0 && reste < 100)
                            {
                                lettre += "quatre-vingts ";
                            }
                            else
                            {
                                lettre += "quatre-vingt ";
                            }
                            break;
                        case 9:
                            dix = true;
                            lettre += "quatre-vingt ";
                            break;
                    } // endSwitch(dizaine)

                    if (unite == 1 &&
                            dizaine != 0 &&
                            dizaine != 1 &&
                            dizaine != 8 &&
                            dizaine != 9)
                    {
                        lettre += "et ";
                    }

                    switch (unite)
                    {
                        case 0:
                            if (dix) lettre += "dix ";
                            break;
                        case 1:
                            if (dix) lettre += "onze ";
                            else if (i != 1000)
                            {
                                lettre += "un ";
                            }
                            break;
                        case 2:
                            if (dix) lettre += "douze ";
                            else lettre += "deux ";
                            break;
                        case 3:
                            if (dix) lettre += "treize ";
                            else lettre += "trois ";
                            break;
                        case 4:
                            if (dix) lettre += "quatorze ";
                            else lettre += "quatre ";
                            break;
                        case 5:
                            if (dix) lettre += "quinze ";
                            else lettre += "cinq ";
                            break;
                        case 6:
                            if (dix) lettre += "seize ";
                            else lettre += "six ";
                            break;
                        case 7:
                            if (dix) lettre += "dix-sept ";
                            else lettre += "sept ";
                            break;
                        case 8:
                            if (dix) lettre += "dix-huit ";
                            else lettre += "huit ";
                            break;
                        case 9:
                            if (dix) lettre += "dix-neuf ";
                            else lettre += "neuf ";
                            break;
                    } // endSwitch(unite)

                    switch (i)
                    {
                        case 1000000000:
                            if (y > 1) lettre += "milliards ";
                            else lettre += "milliard ";
                            break;
                        case 1000000:
                            if (y > 1) lettre += "millions ";
                            else lettre += "million ";
                            break;
                        case 1000:
                            lettre += "mille ";
                            break;
                    }
                } // end if(y!=0)
                reste -= y * i;
                dix = false;
            } // end for
            if (lettre.Length == 0) lettre += "zero";

            return lettre.TrimEnd();
        }
        #endregion

        #region English Number
        /// <summary>
        /// Converts the number to text en.
        /// </summary>
        /// <param name="p_dNumber">The number.</param>
        /// <returns></returns>
        public static string ConvertNumberToTextEn(decimal p_dNumber,
            string p_sCurrencyText)
        {
            decimal integerPart = Math.Truncate(p_dNumber);
            decimal decimalPart = (p_dNumber - integerPart) * 100;

            string integerPartString = "";

            integerPartString = string.Format("{0} {1}",
                ConvertNumberEn(integerPart),
                p_sCurrencyText);

            string decimalPartString = string.Empty;
            if (decimalPart > 0)
            {
                decimalPartString = String.Format(" and {0}", ConvertNumberEn(decimalPart));
            }

            return String.Format(
                "{0}{1}",
                integerPartString,
                decimalPartString).Trim();

        }

        /// <summary>
        /// Converts the number to word.
        /// </summary>
        /// <param name="nNumber">The n number.</param>
        /// <returns></returns>
        private static string ConvertNumberEn(decimal nNumber)
        {
            long CurrentNumber = Convert.ToInt64(nNumber);
            string sReturn = "";
            if (CurrentNumber >= 1000000000)
            {
                sReturn = sReturn + " " + GetWord(CurrentNumber / 1000000000, "Billion");
                CurrentNumber = CurrentNumber % 1000000000;
            }

            if (CurrentNumber >= 1000000)
            {
                sReturn = sReturn + " " + GetWord(CurrentNumber / 1000000, "Million");
                CurrentNumber = CurrentNumber % 1000000;
            }

            if (CurrentNumber >= 1000)
            {
                sReturn = sReturn + " " + GetWord(CurrentNumber / 1000, "Thousand");
                CurrentNumber = CurrentNumber % 1000;
            }

            if (CurrentNumber >= 100)
            {
                sReturn = sReturn + " " + GetWord(CurrentNumber / 100, "Hundred");
                CurrentNumber = CurrentNumber % 100;
            }

            if (CurrentNumber >= 20)
            {
                sReturn = sReturn + " " + GetWord(CurrentNumber, "");
                CurrentNumber = CurrentNumber % 10;
            }

            else if (CurrentNumber > 0)
            {
                sReturn = sReturn + " " + GetWord(CurrentNumber, "");
                CurrentNumber = 0;
            }
            return sReturn.Trim();
        }

        /// <summary>
        /// Gets the word.
        /// </summary>
        /// <param name="nNumber">The n number.</param>
        /// <param name="sPrefix">The s prefix.</param>
        /// <returns></returns>
        private static string GetWord(decimal nNumber, string sPrefix)
        {
            long nCurrentNumber = Convert.ToInt64(nNumber);
            string sReturn = "";
            while (nCurrentNumber > 0)
            {
                if (nCurrentNumber >= 100)
                {
                    sReturn = sReturn + " " + GetWord(nCurrentNumber / 100, "Hundred");
                    nCurrentNumber = nCurrentNumber % 100;
                }

                else if (nCurrentNumber >= 20)
                {
                    sReturn = sReturn + " " + GetTwentyWord(nCurrentNumber / 10);
                    nCurrentNumber = nCurrentNumber % 10;
                }
                else
                {
                    sReturn = sReturn + " " + GetLessThanTwentyWord(nCurrentNumber);
                    nCurrentNumber = 0;
                }

            }
            sReturn = sReturn + " " + sPrefix;
            return sReturn.Trim();
        }

        /// <summary>
        /// Gets the twenty word.
        /// </summary>
        /// <param name="nNumber">The n number.</param>
        /// <returns></returns>
        private static string GetTwentyWord(decimal nNumber)
        {
            string sReturn = "";
            switch (Convert.ToInt64(nNumber))
            {
                case 2:
                    sReturn = "Twenty";
                    break;
                case 3:
                    sReturn = "Thirty";
                    break;
                case 4:
                    sReturn = "Forty";
                    break;
                case 5:
                    sReturn = "Fifty";
                    break;
                case 6:
                    sReturn = "Sixty";
                    break;
                case 7:
                    sReturn = "Seventy";
                    break;
                case 8:
                    sReturn = "Eighty";
                    break;
                case 9:
                    sReturn = "Ninety";
                    break;
            }
            return sReturn;
        }

        /// <summary>
        /// Gets the less than twenty word.
        /// </summary>
        /// <param name="nNumber">The n number.</param>
        /// <returns></returns>
        private static string GetLessThanTwentyWord(decimal nNumber)
        {
            string sReturn = "";
            switch (Convert.ToInt64(nNumber))
            {
                case 1:
                    sReturn = "One";
                    break;
                case 2:
                    sReturn = "Two";
                    break;
                case 3:
                    sReturn = "Three";
                    break;
                case 4:
                    sReturn = "Four";
                    break;
                case 5:
                    sReturn = "Five";
                    break;
                case 6:
                    sReturn = "Six";
                    break;
                case 7:
                    sReturn = "Seven";
                    break;
                case 8:
                    sReturn = "Eight";
                    break;
                case 9:
                    sReturn = "Nine";
                    break;
                case 10:
                    sReturn = "Ten";
                    break;
                case 11:
                    sReturn = "Eleven";
                    break;
                case 12:
                    sReturn = "Twelve";
                    break;
                case 13:
                    sReturn = "Thirteen";
                    break;
                case 14:
                    sReturn = "Forteen";
                    break;
                case 15:
                    sReturn = "Fifteen";
                    break;
                case 16:
                    sReturn = "Sixteen";
                    break;
                case 17:
                    sReturn = "Seventeen";
                    break;
                case 18:
                    sReturn = "Eighteen";
                    break;
                case 19:
                    sReturn = "Nineteen";
                    break;
            }
            return sReturn;
        }

        #endregion
    }
}
